1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 module hip.hipaudio.backend.alefx;
12 version(OpenAL):
13 import bindbc.openal;
14 import hip.error.handler;
15 
16 /**
17 * Is using EAX Reverb
18 */
19 static bool usingEAXReverb = false;
20 
21 /**
22 * Returns an ALEffect index back to be used on a slot
23 * Code took from KCat OpenAL Soft
24 */
25 ALuint loadReverb(ref ReverbProperties r)
26 {
27     ALuint effect;
28 
29     alGenEffects(1, &effect);
30     if(alGetEnumValue("AL_EFFECT_EAXREVERB") != 0)
31     {
32         usingEAXReverb = true;
33         /* EAX Reverb is available. Set the EAX effect type then load the
34          * reverb properties. */
35         alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
36 
37         ALfloat* reflecPan = &r.reflectionsPan[0];
38         ALfloat* lateRevPan = &r.lateReverbPan[0];
39 
40         alEffectf(effect, AL_EAXREVERB_DENSITY, r.density);
41         alEffectf(effect, AL_EAXREVERB_DIFFUSION, r.diffusion);
42         alEffectf(effect, AL_EAXREVERB_GAIN, r.gain);
43         alEffectf(effect, AL_EAXREVERB_GAINHF, r.gainHF);
44         alEffectf(effect, AL_EAXREVERB_GAINLF, r.gainLF);
45         alEffectf(effect, AL_EAXREVERB_DECAY_TIME, r.decayTime);
46         alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, r.decayHFRatio);
47         alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, r.decayLFRatio);
48         alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, r.reflectionsGain);
49         alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, r.reflectionsDelay);
50         alEffectfv(effect,AL_EAXREVERB_REFLECTIONS_PAN, reflecPan);
51         alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, r.lateReverbGain);
52         alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, r.lateReverbDelay);
53         alEffectfv(effect,AL_EAXREVERB_LATE_REVERB_PAN, lateRevPan);
54         alEffectf(effect, AL_EAXREVERB_ECHO_TIME, r.echoTime);
55         alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, r.echoDepth);
56         alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, r.modulationTime);
57         alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, r.modulationDepth);
58         alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, r.airAbsorptionGainHF);
59         alEffectf(effect, AL_EAXREVERB_HFREFERENCE, r.HFReference);
60         alEffectf(effect, AL_EAXREVERB_LFREFERENCE, r.LFReference);
61         alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, r.roomRolloffFactor);
62         alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, r.decayHFLimit);
63     }
64     else
65     {
66         usingEAXReverb = false;
67 
68         /* No EAX Reverb. Set the standard reverb effect type then load the
69          * available reverb properties. */
70         alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
71 
72         alEffectf(effect, AL_REVERB_DENSITY, r.density);
73         alEffectf(effect, AL_REVERB_DIFFUSION, r.diffusion);
74         alEffectf(effect, AL_REVERB_GAIN, r.gain);
75         alEffectf(effect, AL_REVERB_GAINHF, r.gainHF);
76         alEffectf(effect, AL_REVERB_DECAY_TIME, r.decayTime);
77         alEffectf(effect, AL_REVERB_DECAY_HFRATIO, r.decayHFRatio);
78         alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, r.reflectionsGain);
79         alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, r.reflectionsDelay);
80         alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, r.lateReverbGain);
81         alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, r.lateReverbDelay);
82         alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, r.airAbsorptionGainHF);
83         alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, r.roomRolloffFactor);
84         alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, r.decayHFLimit);
85     }
86 
87     /* Check if an error occured, and clean up if so. */
88     int err = alGetError();
89     if(err != AL_NO_ERROR)
90     {
91         import hip.util.conv:to;
92         
93         string str = to!string(alGetString(err));
94         ErrorHandler.showErrorMessage("OpenAL error: "~str~"\n", "Reverb Error");
95         if(alIsEffect(effect))
96             alDeleteEffects(1, &effect);
97         return 0;
98     }
99 
100     return effect;
101 }